package com.zt.chatgpt.openai.service.rule.factory;

import com.zt.chatgpt.openai.annotation.LogicStrategy;
import com.zt.chatgpt.openai.model.aggregates.UserAccountQuotaEntity;
import com.zt.chatgpt.openai.service.rule.ILogicFilter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: zt
 * @Description: 规则工厂
 * @create: 2024-05-21 23:33
 */

@Service
public class DefaultLogicFactory {


    public Map<String, ILogicFilter<UserAccountQuotaEntity>> logicFilterMap = new ConcurrentHashMap<>();

    /**
     * 构造函数: 通过遍历给定的逻辑过滤器列表，将每个过滤器根据其逻辑模式注册到逻辑过滤器映射中。
     *
     * @param logicFilters 逻辑过滤器列表，包含需要注册的所有逻辑过滤器。
     *                     每个过滤器必须由 LogicStrategy 注解标记，以指定其逻辑模式。
     */
    public DefaultLogicFactory(List<ILogicFilter<UserAccountQuotaEntity>> logicFilters) {
        // 遍历逻辑过滤器列表，将每个过滤器根据其逻辑模式添加到映射中
        logicFilters.forEach(logic ->{
            // 寻找逻辑过滤器类上的 LogicStrategy 注解
            LogicStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LogicStrategy.class);
            // 如果找到注解，则根据逻辑模式的代码将过滤器添加到映射中
            if (null != strategy) {
                logicFilterMap.put(strategy.logicMode().getCode(), logic);
            }
        });
    }

    public Map<String, ILogicFilter<UserAccountQuotaEntity>> openLogicFilter() {
        return logicFilterMap;
    }

    /**
     * 规则逻辑枚举
     */
    public enum LogicModel {
        NULL("NULL", "直接放行不用过滤"),
        ACCESS_LIMIT("ACCESS_LIMIT", "访问次数过滤"),
        SENSITIVE_WORD("SENSITIVE_WORD", "敏感词过滤"),
        USER_QUOTA("USER_QUOTA", "用户配额过滤"),
        MODEL_TYPE("MODEL_TYPE", "模型类型过滤"),
        ACCOUNT_STATUS("ACCOUNT_STATUS", "账号状态过滤"),
        ;

        private String code;
        private String info;

        LogicModel(String code, String info) {
            this.code = code;
            this.info = info;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getInfo() {
            return info;
        }

        public void setInfo(String info) {
            this.info = info;
        }
    }
}
